package com.base.essearch.video.task;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.base.essearch.common.FileUploadConfig;
import com.base.essearch.es.bean.MovieEntity;
import com.base.essearch.es.service.IMovieService;
import com.base.essearch.utils.HlsVideoUtil;
import com.base.essearch.utils.Mp4VideoUtil;
import com.base.essearch.utils.StringUtils;
import com.base.essearch.video.entity.VideoMediaFile;
import com.base.essearch.video.entity.media.MediaFileProcessM3u8;
import com.base.essearch.video.mapper.VideoMediaFileMapper;
import com.base.essearch.video.service.IVideoMediaFileService;
import com.base.essearch.webupload.dao.FileRecordMapper;
import com.base.essearch.webupload.entity.FileRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Administrator
 * @version 1.0
 **/
@Component
@Slf4j
public class MediaProcessTask {


    @Value("${task_transfer_ffmpeg_path}")
    String ffmpegPath;
    public static String serverPath;
    @Autowired
    private VideoMediaFileMapper videoMediaFileMapper;
    @Autowired
    private FileRecordMapper fileRecordMapper;
    @Autowired
    private FileUploadConfig fileUploadConfig;
    @Autowired
    private IVideoMediaFileService videoMediaFileService;
    @Autowired
    private IMovieService movieService;

    @PostConstruct
    public void initEs() {
        List<FileRecord> fileRecords = fileRecordMapper.selectList(
                Wrappers.<FileRecord>lambdaQuery()
                        .eq(FileRecord::getM3u8Transfer, 8)
                        .eq(FileRecord::getIsMerge, 1)
        );
        saveAllToES(fileRecords);
    }

    private List<MovieEntity> saveAllToES(List<FileRecord> fileRecords) {
        List<MovieEntity> list = new ArrayList<>();

        for (FileRecord fileRecord : fileRecords) {
            MovieEntity entity = new MovieEntity();
            VideoMediaFile mediaFile = videoMediaFileMapper.selectById(fileRecord.getMd5Value());
            entity.setMovieId(mediaFile.getFileId());
            entity.setCreateDate(mediaFile.getUploadTime());
            String name = StringUtils.isBlank(fileRecord.getSearchKey()) ? fileRecord.getOrgName() : fileRecord.getSearchKey();
            entity.setMovieName(name);
            entity.setTag(mediaFile.getTag());
            list.add(entity);
        }
        movieService.saveBatchMovie(list);
        return list;
    }

    @Scheduled(cron = "0/50 * * * * ?")
    public void transfer() {
        List<FileRecord> fileRecords = fileRecordMapper.selectList(
                Wrappers.<FileRecord>lambdaQuery()
                        .eq(FileRecord::getM3u8Transfer, 2)
                        .eq(FileRecord::getIsMerge, 1)
        );
        for (FileRecord fileRecord : fileRecords) {
            receiveMediaProcessTask(fileRecord);
        }
    }

    //接收视频处理消息进行视频处理
    public void receiveMediaProcessTask(FileRecord fileRecord) {
        //1、解析消息内容，得到mediaId
        String mediaId = fileRecord.getMd5Value();
        //2、拿mediaId从数据库查询文件信息

        VideoMediaFile mediaFile = videoMediaFileMapper.selectById(mediaId);
        if (mediaFile == null) {
            mediaFile = new VideoMediaFile();
            adptor(mediaFile, fileRecord);
        } else {
            log.info("文件已转换过" + mediaFile.toString());
            // 修改设置成转换成功
            updateFileRecordTransfer(fileRecord);
            // 重置 es 索引
            // 生成m3u8 保存到es
            videoMediaFileService.saveToEs(mediaFile, fileRecord);
            return;
        }

        //文件类型
        String fileType = mediaFile.getFileType();
        if ("mp4".equals(fileType)) {
            createM3U8ByMp4(mediaFile, fileRecord);
        } else if ("avi".equals(fileType)) {
            adptorAviToMp4(mediaFile, fileRecord);
        } else {
            log.info("没有转换的视频格式 {}", fileRecord.toString());
        }
    }

    private void updateFileRecordTransfer(FileRecord fileRecord) {
        FileRecord up = new FileRecord();
        up.setM3u8Transfer(8);
        up.setId(fileRecord.getId());
        fileRecordMapper.updateById(up);
    }

    private void adptorAviToMp4(VideoMediaFile mediaFile, FileRecord fileRecord) {
        //3、使用工具类将avi文件生成mp4
        //String ffmpeg_path, String video_path, String mp4_name, String mp4folder_path
        //要处理的视频文件的路径
        // String video_path = serverPath + mediaFile.getFilePath() + mediaFile.getFileName();
        String video_path = mediaFile.getFilePath();
        //生成的mp4的文件名称
        String mp4_name = mediaFile.getFileId() + ".mp4";
        //生成的mp4所在的路径
        String mp4folder_path = serverPath + getPath(fileRecord) + "mp4/";
        //创建工具类对象
        Mp4VideoUtil mp4VideoUtil = new Mp4VideoUtil(ffmpegPath, video_path, mp4_name, mp4folder_path);
        //进行处理
        String result = mp4VideoUtil.generateMp4();
        if (!"success".equals(result)) {
            //处理失败
            mediaFile.setProcessStatus("303003");
            //定义mediaFileProcess_m3u8
            MediaFileProcessM3u8 mediaFileProcess_m3U8 = new MediaFileProcessM3u8();
            //记录失败原因
            mediaFile.setErrormsg(result);
            mediaFile.setMediaFileProcessM3U8(mediaFileProcess_m3U8);
            videoMediaFileMapper.insert(mediaFile);
            return;
        }
        mediaFile.setFilePath(mp4folder_path + mp4_name);
        createM3U8ByMp4(mediaFile, fileRecord);
    }


    private void createM3U8ByMp4(VideoMediaFile mediaFile, FileRecord fileRecord) {

        //4、将mp4生成m3u8和ts文件
        //String ffmpeg_path, String video_path, String m3u8_name,String m3u8folder_path
        //mp4视频文件路径
        String mp4_video_path = mediaFile.getFilePath();
        //m3u8_name文件名称
        String m3u8_name = mediaFile.getFileId() + ".m3u8";
        //m3u8文件所在目录
        String m3u8folder_path = serverPath + getPath(fileRecord) + "hls/";
        log.info("m3u8 文件路径 {}，{}", m3u8folder_path, m3u8_name);
        HlsVideoUtil hlsVideoUtil = new HlsVideoUtil(ffmpegPath, mp4_video_path, m3u8_name, m3u8folder_path);
        //生成m3u8和ts文件
        String tsResult = hlsVideoUtil.generateM3u8();
        if (tsResult == null || !tsResult.equals("success")) {
            //处理失败
            mediaFile.setProcessStatus("303003");
            //定义mediaFileProcess_m3u8
            MediaFileProcessM3u8 mediaFileProcess_m3U8 = new MediaFileProcessM3u8();
            //记录失败原因
            mediaFile.setErrormsg(tsResult);
            mediaFile.setMediaFileProcessM3U8(mediaFileProcess_m3U8);
            videoMediaFileMapper.insert(mediaFile);
            return;
        }
        //处理成功
        //获取ts文件列表
        List<String> ts_list = hlsVideoUtil.get_ts_list();

        mediaFile.setProcessStatus("303002");
        //定义mediaFileProcess_m3u8
        MediaFileProcessM3u8 mediaFileProcess_m3U8 = new MediaFileProcessM3u8();
        mediaFileProcess_m3U8.setTslist(ts_list);
        mediaFile.setMediaFileProcessM3U8(mediaFileProcess_m3U8);
        mediaFile.setM3u8List(JSONObject.toJSONString(ts_list));

        String saticAccess = fileUploadConfig.getStaticAccessPath().replace("*", "");
        //保存fileUrl（此url就是视频播放的相对路径）
        String fileUrl = saticAccess + getPath(fileRecord) + "hls/" + m3u8_name;
        mediaFile.setFileUrl(fileUrl);
        log.info("m3u8 fileUrl  {}", fileUrl);
        System.out.println(mediaFile);
        videoMediaFileMapper.insert(mediaFile);

        // 生成m3u8 保存到es
        videoMediaFileService.saveToEs(mediaFile, fileRecord);
    }

    private String getPath(FileRecord fileRecord) {
        return "m3u8/" + fileRecord.getId() + "/" + fileRecord.getMd5Value() + "/";
    }

    private void adptor(VideoMediaFile mediaFile, FileRecord fileRecord) {

        mediaFile.setFileName(fileRecord.getServerLocalName());
        mediaFile.setFileOriginalName(fileRecord.getOrgName());
        mediaFile.setFileId(fileRecord.getMd5Value());
        mediaFile.setFilePath(fileRecord.getServerLocalPath());
        mediaFile.setFileUrl(fileRecord.getNetworkPath());
        mediaFile.setFileSize(fileRecord.getFileSize());
        mediaFile.setFileType(fileRecord.getOrgName().substring(fileRecord.getOrgName().lastIndexOf(".") + 1));
        mediaFile.setTag(fileRecord.getFileType());
        mediaFile.setUploadTime(fileRecord.getCreateTime());
        mediaFile.setMimeType(fileRecord.getFileType());
    }
}
